'''
Created on Jul 9, 2011

@author: Cihat Basol
'''

from PyQt4.QtGui import *
from PyQt4.QtCore import QAbstractTableModel, QModelIndex, QVariant, Qt
                          
from dexen.system.client import ui
from dexen.system.client import db
from dexen.system.common.states import JobState
from dexen.system.client.ui.widgets.table_view import TableView


JOB_ID = 0
JOB_NAME = 1
JOB_STAT = 2
START_TIME = 3
ELAPSED_TIME = 4
TOTAL_BIRTH = 5
AVG_TIME_IND = 6

svr_proxy = ui.svr_proxy

_labels = [
"Job id:",
"Job name:",
"Job status:",
"Start time:",
"Elapsed time:",
"Total birth:",
"Avg time per individual:"
]


class JobInfoModel(QAbstractTableModel):
    def __init__(self, info_items, parent=None):
        QAbstractTableModel.__init__(self, parent)
        self._info_items = info_items
        self._header = ["Task Name", "Input Size", "Success", "Failure", 
                        "Avg Execution Time"]
    
    def rowCount(self, index=QModelIndex()):
        return len(self._info_items)
    
    def columnCount(self, index=QModelIndex()):
        return len(self._header)

    def data(self, index, role):
        assert isinstance(index, QModelIndex)
        if not index.isValid(): return QVariant()
        
        if role == Qt.DisplayRole:
            item = self._info_items[index.row()][index.column()]
            if index.column() == 4:
                return QVariant("{0:.3f}".format(item) + " seconds")
            else:
                return QVariant(item)
            
    def headerData(self, section, orientation, role=Qt.DisplayRole):
        if role != Qt.DisplayRole:
            return QVariant()
        if orientation == Qt.Horizontal:
            return QVariant(self._header[section])


class SummaryPage(QWidget):
    def __init__(self):
        super(SummaryPage, self).__init__()
        self.widgets = {}
        self.curJobInfo = None
        self.jobStates = {} # job_info:JobState
        self._setupWidgets()
        
    def _setupWidgets(self):
        # Create widgets
        for i in xrange(7):
            self.widgets[i] = QLabel()
        self.tableView = TableView()
        self.breakdownLabel = QLabel("Task executions breakdown:")

        # Configure widgets
        self.tableView.setModel(JobInfoModel([]))
        header = self.tableView.horizontalHeader()
        assert isinstance(header, QHeaderView)
        self.tableView.resizeColumnsToContents()
        
        # Setup layout
        vLayout = QVBoxLayout()
        formLayout = QFormLayout()
        for i in xrange(7):
            formLayout.addRow(_labels[i], self.widgets[i])        
        
        groupBox = QGroupBox("Job Summary")
        groupBox.setLayout(formLayout)
        
        vLayout.addWidget(groupBox)
        vLayout.addWidget(QLabel(""))
        vLayout.addWidget(self.breakdownLabel)
        vLayout.addWidget(self.tableView)
        self.setLayout(vLayout)

    def _update_widget(self, index, value):
        label = self.widgets[index]
        assert isinstance(label, QLabel)
        if index == AVG_TIME_IND:
            label.setText("{0:.3f} seconds".format(value))
        else:
            label.setText(str(value))
    
    def _get_cur_job_state(self):
        if not self.jobStates.has_key(self.curJobInfo): 
            return None
        return self.jobStates[self.curJobInfo] 
    
    def _update_widgets(self):
        job_state = self._get_cur_job_state()
        if job_state == None: return
        assert isinstance(job_state, JobState)
        # update widgets
        self._update_widget(JOB_ID, job_state.get_id())
        self._update_widget(JOB_NAME, job_state.get_name())
        self._update_widget(JOB_STAT, job_state.get_status())
        self._update_widget(START_TIME, job_state.get_start_time_str())
        self._update_widget(ELAPSED_TIME, job_state.get_elapsed_time())
        self._update_widget(TOTAL_BIRTH, job_state.tot_births)
        self._update_widget(AVG_TIME_IND, job_state.get_avg_time_per_ind())
        tasks_info = job_state.get_tasks_info()
        model = JobInfoModel(tasks_info)
        self.tableView.setModel(model)
        self.tableView.resizeColumnsToContents()

    def on_cur_job_changed(self, job_info):
        self.curJobInfo = job_info
        self._update_widgets()

    def on_server_info_updated(self, svr_info):
        assert isinstance(svr_info, db.ServerInfo)
        for job_info in svr_info.get_jobs().values():
            assert isinstance(job_info, db.JobInfo)
            job_state = job_info.get_job_state()
            assert isinstance(job_state, JobState)
            self.jobStates[job_info] = job_state
        self._update_widgets()

    def on_server_info_initialized(self, svr_info_list):
        for svr_info in svr_info_list:
            self.on_server_info_updated(svr_info)
            


